{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Weather map" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook shows an example of use of the `AppLayout` template, which is documented in [Layout Templates](Layout%20Templates.ipynb) notebook. You can check that notebook for further explanation.\n", "\n", "This notebook depends on extra packages:\n", "\n", "* [bqplot](https://github.com/bloomberg/bqplot) - widget-based plotting library,\n", "* [ipyleaflet](https://github.com/jupyter-widgets/ipyleaflet) - cartography widget based on leaflet.js \n", "\n", "If you also would like to see a color weather map, you will need to obtain an API key from [OpenWeatherMap](https://openweathermap.org/)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": ["remove-cell"] }, "outputs": [], "source": [ "# Imports for JupyterLite\n", "%pip install -q ipywidgets ipyleaflet numpy bqplot pandas" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from ipyleaflet import Map, basemaps, basemap_to_tiles, Heatmap, TileLayer\n", "from ipywidgets import AppLayout\n", "from ipywidgets import HTML, Layout, Dropdown, Output, Textarea, VBox, Label\n", "import bqplot as bq\n", "import numpy as np\n", "from pandas import date_range" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To see map overlays obtain your API key free of charge from [OpenWeatherMap](https://openweathermap.org/) and paste it below." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "OWM_API_KEY = \"PASTE_YOUR_OWM_API_KEY_HERE\" #openweathermap API key" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m = Map(center=(52, 10), zoom=5, basemap=basemaps.OpenStreetMap.Mapnik)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "maps = {'Mapnik' : basemaps.OpenStreetMap.Mapnik,\n", " 'Esri' : basemaps.Esri.DeLorme}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "header = HTML(\"

Fictional World Weather

\", layout=Layout(height='auto'))\n", "header.style.text_align='center'\n", "basemap_selector = Dropdown( options = list(maps.keys()),\n", " layout=Layout(width='auto'))\n", "\n", "heatmap_selector = Dropdown(options=('Temperature', 'Precipitation'),\n", " layout=Layout(width='auto'))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "basemap_selector.value = 'Mapnik'\n", "m.layout.height='600px'" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "security_1 = np.cumsum(np.random.randn(150)) + 100.\n", "\n", "dates = date_range(start='01-01-2007', periods=150)\n", "\n", "dt_x = bq.DateScale()\n", "sc_y = bq.LinearScale()\n", "\n", "time_series = bq.Lines(x=dates, y=security_1, scales={'x': dt_x, 'y': sc_y})\n", "ax_x = bq.Axis(scale=dt_x)\n", "ax_y = bq.Axis(scale=sc_y, orientation='vertical')\n", "\n", "fig = bq.Figure(marks=[time_series], axes=[ax_x, ax_y],\n", " fig_margin=dict(top=0, bottom=80, left=30, right=20))\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.layout.width='auto'\n", "m.layout.height='auto'\n", "fig.layout.width='auto'\n", "fig.layout.height='auto'" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "out = HTML(\n", " value='',\n", " layout=Layout(width='auto', height='auto')\n", ")\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "AppLayout(center=m, \n", " header=header,\n", " left_sidebar=VBox([Label(\"Basemap:\"),\n", " basemap_selector,\n", " Label(\"Overlay:\"),\n", " heatmap_selector]),\n", " right_sidebar=fig,\n", " footer=out,\n", " pane_widths=['80px', 1, 1],\n", " pane_heights=['80px', 4, 1],\n", " height='600px',\n", " grid_gap=\"30px\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rows = []" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "X, Y = np.mgrid[-90:90:10j, -180:180:20j]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "X = X.flatten()\n", "Y = Y.flatten()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "temps = np.random.randn(200, 150)*0.5" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from datetime import datetime" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import random" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def add_log(msg):\n", " max_rows = 3\n", " rows.append(msg)\n", " if len(rows) > max_rows:\n", " rows.pop(0)\n", " return '

Activity log

'.format('
  • '.join([''] + rows))\n", "\n", "def generate_temp_series(x, y):\n", " if heatmap_selector.value == 'Precipitation':\n", " temp = np.cumsum(np.random.randn(150)) + 100.\n", " elif heatmap_selector.value == 'Temperature':\n", " dist = np.sqrt((X - x)**2 + (Y-y)**2) / 100\n", " dist = dist.max() - dist\n", " dist[dist > np.percentile(dist, 5)] = 0\n", " temp = np.cumsum(np.dot(dist, temps)+0.05) + 20 - np.abs(x) / 2\n", " time_series.y = temp\n", " \n", "def handle_interaction(**kwargs):\n", " if kwargs['type'] == 'click':\n", " generate_temp_series(*kwargs['coordinates'])\n", " msg = '%s Selected coordinates: %s, Temp: %d C Precipitation: %d mm\\n' % (\n", " datetime.now(), kwargs['coordinates'], random.randint(-20, 20), random.randint(0, 100))\n", " out.value = add_log(msg)\n", "\n", "m.on_interaction(handle_interaction) \n", "\n", "def on_map_selected(change):\n", " m.layers = [basemap_to_tiles(maps[basemap_selector.value]), weather_maps[heatmap_selector.value]]\n", " \n", "basemap_selector.observe(on_map_selected, names='value')\n", "heatmap_selector.observe(on_map_selected, names='value')\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "temp = TileLayer(min_zoom=1, max_zoom=18, url='https://tile.openweathermap.org/map/temp_new/{z}/{x}/{y}.png?appid='+OWM_API_KEY, name='owm', attribute='me')\n", "precipitation = TileLayer(min_zoom=1, max_zoom=18, url='https://tile.openweathermap.org/map/precipitation_new/{z}/{x}/{y}.png?appid='+OWM_API_KEY, name='owm', attribute='me')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "weather_maps = {'Temperature' : temp,\n", " 'Precipitation' : precipitation}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.add_layer(weather_maps[heatmap_selector.value])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.5" } }, "nbformat": 4, "nbformat_minor": 2 }